package com.zmn.oms.business.impl.order;

import com.alibaba.fastjson.JSON;
import com.zmn.base.common.data.common.dro.company.CompanyDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.base.common.data.dubbo.interfaces.company.CompanyListRemoteService;
import com.zmn.base.product.common.dto.product.erp.FaultWarrantyDRO;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductForeignListRemoteService;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductTagsGroupForeignListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto.VtDTO;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.business.interfaces.base.BasePlatService;
import com.zmn.oms.business.interfaces.es.OrderWorkEsBService;
import com.zmn.oms.business.interfaces.factory.OrderFactoryBService;
import com.zmn.oms.business.interfaces.master.OrderMasterBService;
import com.zmn.oms.business.interfaces.order.OrderBService;
import com.zmn.oms.business.interfaces.order.OrderProcessBService;
import com.zmn.oms.business.interfaces.order.SimpleOrderBService;
import com.zmn.oms.business.interfaces.product.OrderProductExtendBService;
import com.zmn.oms.business.interfaces.serviceitem.OrderServiceItemBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.work.OrderWorkAmountBService;
import com.zmn.oms.business.interfaces.work.OrderWorkBService;
import com.zmn.oms.business.interfaces.work.orderpay.FactoryAccountModifyBService;
import com.zmn.oms.common.constant.OmsErrorCodeConsts;
import com.zmn.oms.common.constant.OrderAdvanceConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dto.MapDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.MobileUtil;
import com.zmn.oms.model.bo.orderamount.OrderAmountCalcBO;
import com.zmn.oms.model.dto.factory.OrderFactoryDTO;
import com.zmn.oms.model.dto.order.OrderDTO;
import com.zmn.oms.model.dto.order.OrderReworkDTO;
import com.zmn.oms.model.dto.order.zmn.ZsNormalAddressOrderDTO;
import com.zmn.oms.model.dto.order.zmn.ZsNormalNewOrderDTO;
import com.zmn.oms.model.dto.order.zmn.ZsNormalUpdateOrderDTO;
import com.zmn.oms.model.dto.product.NewOrderAdvanceQuoteDTO;
import com.zmn.oms.model.dto.product.OrderProductDTO;
import com.zmn.oms.model.dto.work.modify.CheckReworkOrderDTO;
import com.zmn.oms.model.dto.work.workamount.WorkUpdateAmountDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.discount.OrderDiscount;
import com.zmn.oms.model.entity.factory.OrderFactory;
import com.zmn.oms.model.entity.masterworking.MasterWorking;
import com.zmn.oms.model.entity.order.Order;
import com.zmn.oms.model.entity.orderfinalpricequotation.OrderFinalPriceQuotation;
import com.zmn.oms.model.entity.orderfinalpricequotation.OrderFinalPriceQuotationQuery;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.discount.OrderDiscountService;
import com.zmn.oms.services.interfaces.factory.OrderFactoryService;
import com.zmn.oms.services.interfaces.masterworking.MasterWorkingService;
import com.zmn.oms.services.interfaces.member.OrderMemberService;
import com.zmn.oms.services.interfaces.orderfinalpricequotation.OrderFinalPriceQuotationService;
import com.zmn.oms.services.interfaces.product.OrderProductExtendService;
import com.zmn.oms.services.interfaces.product.OrderProductService;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyProductService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyService;
import com.zmn.oms.services.interfaces.work.OrderWorkAmountService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.sp.common.enums.available.AvailableAreaLevelEnum;
import com.zmn.sp.dubbo.interfaces.available.AvailableAreaListRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.curator.shaded.com.google.common.collect.Lists;
import org.apache.dubbo.config.annotation.Reference;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 类描述：
 *
 * @author liuying
 * @date 2018/12/20 14:30
 */
@Slf4j
public abstract class OrderBaseBServiceImpl {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected ProductTagsGroupForeignListRemoteService productTagsGroupForeignListRemoteService;
    @Reference(version = com.zmn.sp.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    protected AvailableAreaListRemoteService availableAreaListRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected CompanyListRemoteService companyListRemoteService;
//    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
//    protected FactoryListRemoteService factoryListRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected AreaListRemoteService areaListRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected ProductForeignListRemoteService productForeignListRemoteService;

    @Autowired
    protected OrderBService orderBService;
    @Autowired
    protected SimpleOrderBService simpleOrderBService;
    @Autowired
    protected OrderProductService orderProductService;
    @Autowired
    protected OrderWorkBService orderWorkBService;
    @Autowired
    protected OrderWorkAmountBService orderWorkAmountBService;
    @Autowired
    protected OrderServiceItemService orderServiceItemService;
    @Autowired
    protected OrderProductExtendService orderProductExtendService;
    @Autowired
    protected OrderWorkAmountService orderWorkAmountService;
    @Autowired
    protected OrderMasterBService masterBService;
    @Autowired
    protected OrderWorkService orderWorkService;
    @Autowired
    protected OrderDetailService orderDetailService;
    @Autowired
    protected MasterWorkingService masterWorkingService;
    @Autowired
    protected OrderDiscountService orderDiscountService;
    @Autowired
    protected OrderFactoryBService orderFactoryBService;
    @Autowired
    protected OrderFactoryService orderFactoryService;
    @Autowired
    protected OrderServiceItemBService orderServiceItemBService;
    @Autowired
    protected OrderProductExtendBService orderProductExtendBService;
    @Autowired
    protected BaseCodeService baseCodeService;
    @Autowired
    protected BasePlatService basePlatService;
    @Autowired
    protected OrderMemberService orderMemberService;
    @Autowired
    protected OrderWarrantyService orderWarrantyService;
    @Autowired
    protected OrderWarrantyProductService orderWarrantyProductService;
    @Autowired
    protected OrderWorkEsBService orderWorkEsBService;
    @Autowired
    protected FactoryAccountModifyBService factoryAccountModifyBService;
    @Autowired
    protected ServItemBService servItemBService;
    @Autowired
    protected OrderProcessBService orderProcessBService;

    /**
     * 保存工程师进行中的工单
     *
     * @param orderId
     * @param workId
     */
    protected void saveMasterWorking(Long orderId, Long workId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);

        // 派单之前不处理
        if (orderWork.getStatus() < OrderStatusConsts.WORK_STATUS_DISTRIBUTE) {
            return;
        }

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);

        MasterWorking masterWorking = BeanMapper.map(orderWork, MasterWorking.class);
        masterWorking.setWorkId(orderWork.getWorkId());
        masterWorking.setStatus(orderWork.getStatus());
        masterWorking.setAddress(String.format("%s%s%s", StringUtils.defaultString(orderDetail.getCountyName()), StringUtils.defaultString(orderDetail.getStreet()), StringUtils.defaultString(orderDetail.getAddress())));
        masterWorking.setLatitude(orderDetail.getLatitude());
        masterWorking.setLongitude(orderDetail.getLongitude());
        masterWorking.setProductInfo(orderDetail.getProductInfo());
        masterWorking.setServCategId(orderDetail.getServCategId());
        masterWorking.setServCategName(orderDetail.getServCategName());
        masterWorking.setServItemType(orderWork.getServItemType());
        masterWorking.setDutyTime(orderWork.getDutyTime());
        masterWorkingService.updateMasterWorking(masterWorking);
    }

    /**
     * zmn 产品处理
     *
     * @param orderProductDTO
     * @return
     */
    protected OrderProduct getProductInfo(OrderProductDTO orderProductDTO) {
        OrderProduct orderProduct = BeanMapper.map(orderProductDTO, OrderProduct.class);

        // 处理故障信息
        if (CollectionUtils.isNotEmpty(orderProductDTO.getFaultIdList())) {
            Integer productId = !NumberUtil.isNullOrZero(orderProductDTO.getProductId()) ? orderProductDTO.getProductId() : orderProductDTO.getShowProductId();
            ResponseDTO<List<FaultWarrantyDRO>> responseDTO = productTagsGroupForeignListRemoteService.listFaultByProductId(productId);
            if (responseDTO.isSuccess() && CollectionUtil.isNotNullOrEmpty(responseDTO.getData())) {
                List<FaultWarrantyDRO> list = responseDTO.getData();
                List<MapDTO> faultList = Lists.newArrayList();
                orderProductDTO.getFaultIdList().forEach(id -> list.stream().filter(ss -> ss.getItemId() == id.intValue()).findAny().ifPresent(e->{
                    MapDTO mapDTO = new MapDTO();
                    mapDTO.setMapId(e.getItemId());
                    mapDTO.setMapName(e.getName());
                    faultList.add(mapDTO);
                }));
                orderProduct.setFault(JSON.toJSONString(faultList));
            }
        }

        return orderProduct;
    }

    /**
     * zmn 产品处理
     *
     * @param orderDTO
     * @return
     */
    protected OrderFinalPriceQuotation getOrderFinalPriceQuotation(OrderDTO orderDTO, ZsNormalNewOrderDTO zsNormalNewOrderDTO, OrderAmountCalcBO amountCalcBO) {
        OrderFinalPriceQuotation orderProductQuotation = new OrderFinalPriceQuotation();

        OrderWork orderWork = orderDTO.getOrderWork();
        OrderProduct orderProduct = orderDTO.getOrderProductList().get(0);
        NewOrderAdvanceQuoteDTO advanceQuoteDTO = zsNormalNewOrderDTO.getOrderProductList().get(0).getAdvanceQuote();
        if (Objects.isNull(advanceQuoteDTO)) {
            return null;
        }

        orderProductQuotation.setOrderId(orderWork.getOrderId());
        orderProductQuotation.setWorkId(orderWork.getWorkId());

        Integer quoteType = advanceQuoteDTO.getQuoteType();
        if (NumberUtil.isNullOrZero(quoteType)) {
            // 冗余处理，如果没有传，判断故障现象ID
            if (NumberUtil.isNotNullOrZero(advanceQuoteDTO.getPhenId())) {
                quoteType = OrderAdvanceConsts.QUOTE_TYPE_FAULT_PHEN;
            } else if (NumberUtil.isNotNullOrZero(advanceQuoteDTO.getItemId())) {
                quoteType = OrderAdvanceConsts.QUOTE_TYPE_SERVICE_ITEM_TYPE;
            } else {
                quoteType = com.zmn.consts.GlobalConsts.NONE;
            }
        }
        orderProductQuotation.setQuotationType(quoteType);

        orderProductQuotation.setCategId(orderProduct.getCategId());
        orderProductQuotation.setCategName(orderProduct.getCategName());
        orderProductQuotation.setProductId(orderProduct.getProductId());
        orderProductQuotation.setProductName(orderProduct.getProductName());
        orderProductQuotation.setShowProductId(orderProduct.getShowProductId());
        orderProductQuotation.setShowProductName(orderProduct.getShowProductName());
        orderProductQuotation.setBrandId(orderProduct.getBrandId());
        orderProductQuotation.setBrandName(orderProduct.getBrandName());
        orderProductQuotation.setTariffName(orderProduct.getTariffName());
        orderProductQuotation.setOldTariffName(orderProduct.getTariffName());

        // 服务项相关信息
        if (CollectionUtil.isNotNullOrEmpty(orderDTO.getOrderServiceItemList())) {
            OrderServiceItem serviceItem = orderDTO.getOrderServiceItemList().get(0);
            orderProductQuotation.setServItemId(serviceItem.getServItemId());
            orderProductQuotation.setServItemName(serviceItem.getServItemName());
            orderProductQuotation.setItemPrice(serviceItem.getItemPrice());
            orderProductQuotation.setItemUnit(serviceItem.getItemUnit());
        }

        if (NumberUtil.isNotNullOrZero(advanceQuoteDTO.getPhenId())) {
            orderProductQuotation.setPhenId(advanceQuoteDTO.getPhenId());
            orderProductQuotation.setPhenName(advanceQuoteDTO.getPhenName());
        }

        orderProductQuotation.setTotalAmount(amountCalcBO.getTotalAmount());

        orderProductQuotation.setCreater(orderWork.getCreater());
        orderProductQuotation.setUpdater(orderWork.getCreater());
        orderProductQuotation.setUpdateTime(orderWork.getCreateTime());
        orderProductQuotation.setCreateTime(orderWork.getCreateTime());

        return orderProductQuotation;
    }

    /**
     * 厂商产品处理，转化为基础产品信息
     *
     * @param orderFactoryDTO
     * @return
     */
    protected OrderProduct  getProductInfo(OrderFactoryDTO orderFactoryDTO) throws OmsBaseException {
        OrderProductDTO orderProductDTO = BeanMapper.map(orderFactoryDTO, OrderProductDTO.class);

        orderProductDTO.setBrandId(GlobalConsts.NONE);
        orderProductDTO.setNumber(orderFactoryDTO.getFcProductNumber());

        return this.getProductInfo(orderProductDTO);
    }

    /**
     * 获取修改订单信息
     *
     * @param zsNormalUpdateOrderDTO
     * @return
     * @throws OmsBaseException
     */
    protected OrderDTO  getUpdateOrderDTO(ZsNormalUpdateOrderDTO zsNormalUpdateOrderDTO) throws OmsBaseException {
        // 原始数据
        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKeySrcMaster(zsNormalUpdateOrderDTO.getOrderId(), zsNormalUpdateOrderDTO.getWorkId());
        OrderDetail dbOrderDetail = orderDetailService.findOrderDetailByKeySrcMaster(zsNormalUpdateOrderDTO.getOrderId());
        OrderFactory dbOrderFactory = orderFactoryService.findOrderFactoryByKey(zsNormalUpdateOrderDTO.getOrderId());
        List<OrderProduct> dbOrderProductList = orderProductService.listOrderProductByOrderId(zsNormalUpdateOrderDTO.getOrderId());
        List<OrderDiscount> dbOrderDiscountList = orderDiscountService.listByOrderId(zsNormalUpdateOrderDTO.getOrderId());


        zsNormalUpdateOrderDTO.setTelephone2(StringUtils.defaultString(zsNormalUpdateOrderDTO.getTelephone2()));
        zsNormalUpdateOrderDTO.setTelephone3(StringUtils.defaultString(zsNormalUpdateOrderDTO.getTelephone3()));

        // 隐藏手机号处理
        if (MobileUtil.isHideTel(zsNormalUpdateOrderDTO.getTelephone())) {
            zsNormalUpdateOrderDTO.setTelephone(dbOrderDetail.getTelephone());
        }
        if (MobileUtil.isHideTel(zsNormalUpdateOrderDTO.getTelephone2())) {
            zsNormalUpdateOrderDTO.setTelephone2(dbOrderDetail.getTelephone2());
        }
        if (MobileUtil.isHideTel(zsNormalUpdateOrderDTO.getTelephone3())) {
            zsNormalUpdateOrderDTO.setTelephone3(dbOrderDetail.getTelephone3());
        }

        Order order = BeanMapper.map(zsNormalUpdateOrderDTO, Order.class);
        OrderDetail orderDetail = BeanMapper.map(zsNormalUpdateOrderDTO, OrderDetail.class);
        OrderWork orderWork = BeanMapper.map(zsNormalUpdateOrderDTO, OrderWork.class);

        // 厂商
        OrderFactory orderFactory = null;
        // 处理用户类型
        orderDetail.setUserType(dbOrderDetail.getUserType());

        // 订单产品
        List<OrderProduct> orderProductList = null;
        if (Objects.equals(OrderConsts.ORDER_SOURCE_TYPE_FACTORY, dbOrderWork.getSourceType())) {

            // 厂商订单信息
            orderFactory = BeanMapper.map(zsNormalUpdateOrderDTO.getOrderFactory(), OrderFactory.class);
            orderFactory.setFcOrderId(zsNormalUpdateOrderDTO.getOrderId());

            // 厂商产品
            orderProductList = Lists.newArrayList( this.getProductInfo(
                    zsNormalUpdateOrderDTO.getOrderFactory()) );

            // 渠道ID
            /*ResponseDTO<FactoryDRO> responseDTO = factoryListRemoteService.getFactoryById(orderFactory.getFactoryId());

            if (responseDTO.getData() != null) {
                orderWork.setChannelId(responseDTO.getData().getChannelId());
            }*/

        } else if (CollectionUtils.isNotEmpty(zsNormalUpdateOrderDTO.getOrderProductList())) {
            // 产品处理
            orderBService.processBeforeOrderProduct(zsNormalUpdateOrderDTO.getOrderProductList().get(0));

            // 普通产品
            orderProductList = Lists.newArrayListWithExpectedSize(zsNormalUpdateOrderDTO.getOrderProductList().size());
            for (OrderProductDTO orderProductDTO : zsNormalUpdateOrderDTO.getOrderProductList()) {
                orderProductList.add(this.getProductInfo(orderProductDTO));
            }

            log.debug("修改订单【{}】产品信息：【{}】", zsNormalUpdateOrderDTO.getOrderId(), orderProductList);
        }

        // 返修单，检查返修单号
        if (Objects.equals(OrderConsts.ORDER_TYPE_REWORK, zsNormalUpdateOrderDTO.getType())) {
            CheckReworkOrderDTO checkReworkOrderDTO = new CheckReworkOrderDTO();
            if (Objects.equals(OrderConsts.ORDER_SOURCE_TYPE_FACTORY, dbOrderWork.getSourceType())) {
                checkReworkOrderDTO.setChannelId(dbOrderWork.getChannelId());
            }
            checkReworkOrderDTO.setPlatWork(dbOrderWork.getPlatWork());
            checkReworkOrderDTO.setOrderId(zsNormalUpdateOrderDTO.getOrderId());
            checkReworkOrderDTO.setCityId(zsNormalUpdateOrderDTO.getCityId());
            checkReworkOrderDTO.setLatitude(zsNormalUpdateOrderDTO.getLatitude());
            checkReworkOrderDTO.setLongitude(zsNormalUpdateOrderDTO.getLongitude());
            checkReworkOrderDTO.setReworkId(zsNormalUpdateOrderDTO.getReworkId());
            checkReworkOrderDTO.setTelephone(zsNormalUpdateOrderDTO.getTelephone());
            checkReworkOrderDTO.setTelephone2(zsNormalUpdateOrderDTO.getTelephone2());
            checkReworkOrderDTO.setTelephone3(zsNormalUpdateOrderDTO.getTelephone3());

            OrderProduct orderProduct = orderProductList.get(0);
            checkReworkOrderDTO.setProductId(!NumberUtil.isNullOrZero(orderProduct.getShowProductId()) ? orderProduct.getShowProductId() : orderProduct.getProductId());
            checkReworkOrderDTO.setProductShowType(!NumberUtil.isNullOrZero(orderProduct.getShowProductId()) ? GlobalConsts.YES : GlobalConsts.NO);
            this.checkReworkId(checkReworkOrderDTO);
        }
        // 记录人确认人和确认时间
        if (Objects.equals(zsNormalUpdateOrderDTO.getStatus(), OrderStatusConsts.WORK_STATUS_CONFIRM)) {
            orderWork.setConfirmTime(DateUtil.getNow());
            orderWork.setConfirmerId( Optional.ofNullable(zsNormalUpdateOrderDTO.getOperatorId())
                    .orElse((long) GlobalConsts.OPERATE_USER_TYPE_SYSTEM) );
        }

        OrderFinalPriceQuotation orderFinalPriceQuotation = null;
        if (Objects.nonNull(zsNormalUpdateOrderDTO.getOrderProductList().get(0).getAdvanceQuote())) {
            NewOrderAdvanceQuoteDTO quoteDTO = zsNormalUpdateOrderDTO.getOrderProductList().get(0).getAdvanceQuote();
            orderFinalPriceQuotation = new OrderFinalPriceQuotation();
            orderFinalPriceQuotation.setOrderId(zsNormalUpdateOrderDTO.getOrderId());
            orderFinalPriceQuotation.setWorkId(zsNormalUpdateOrderDTO.getWorkId());
            orderFinalPriceQuotation.setQuotationType(quoteDTO.getQuoteType());
            orderFinalPriceQuotation.setServItemId(quoteDTO.getItemId());
            orderFinalPriceQuotation.setPhenId(quoteDTO.getPhenId());
            orderFinalPriceQuotation.setPhenName(quoteDTO.getPhenName());
        }


        // 保存订单
        OrderDTO orderDTO = BeanMapper.map(zsNormalUpdateOrderDTO, OrderDTO.class);
        orderDTO.setEquityType(zsNormalUpdateOrderDTO.getEquityType());
        orderDTO.setOrder(order);
        orderDTO.setOrderDetail(orderDetail);
        orderDTO.setOrderProductList(orderProductList);
        orderDTO.setOrderWork(orderWork);
        orderDTO.setOrderFactory(orderFactory);
        orderDTO.setOrderFinalPriceQuotation(orderFinalPriceQuotation);

        // 原始数据
        orderDTO.setDbOrderWork(dbOrderWork);
        orderDTO.setDbOrderDetail(dbOrderDetail);
        orderDTO.setDbOrderProductList(dbOrderProductList);
        orderDTO.setDbOrderFactory(dbOrderFactory);
        orderDTO.setOrderDiscountList(dbOrderDiscountList);

        // 修改时，用户ID不变
        orderWork.setPlat(dbOrderWork.getPlat());
        orderWork.setPlatWork(dbOrderWork.getPlatWork());
        orderWork.setSourceType(dbOrderWork.getSourceType());
        orderWork.setUserId(dbOrderWork.getUserId());
        orderWork.setChannelId(Optional.ofNullable(orderWork.getChannelId()).orElse(dbOrderWork.getChannelId()));
        orderWork.setChannelName(Optional.ofNullable(orderWork.getChannelName()).orElse(dbOrderWork.getChannelName()));
        orderWork.setNextContactTime(Optional.ofNullable(orderWork.getNextContactTime()).orElse(dbOrderWork.getNextContactTime()));
        orderWork.setBizType(dbOrderWork.getBizType());

        order.setPlat(dbOrderWork.getPlat());
        order.setPlatWork(dbOrderWork.getPlatWork());
        order.setSourceType(dbOrderWork.getSourceType());
        order.setUserId(dbOrderWork.getUserId());
        order.setBizType(dbOrderWork.getBizType());

        // 厂商单处理，不能修改厂商
        if (Objects.equals(dbOrderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)) {
            orderWork.setChannelId(dbOrderWork.getChannelId());
            orderWork.setChannelName(dbOrderWork.getChannelName());
            orderWork.setChannelOneId(dbOrderWork.getChannelOneId());
            orderWork.setChannelTwoId(dbOrderWork.getChannelTwoId());
        }

        // 会员数据处理
        boolean isMemberOrder = dbOrderWork.getMember() != null && Objects.equals(dbOrderWork.getMember(), GlobalConsts.YES);
        if (isMemberOrder) {

            // 手机号不能修改
            orderDetail.setTelephone(dbOrderDetail.getTelephone());

            // 处理会员信息
            // this.processMemberOrder(orderDTO);
        }

        // 订单处理
        orderBService.processOrder(orderDTO);
        orderFactoryBService.processOrderFactory(orderDTO);
        orderWorkBService.processOrderWork(orderDTO);

        // 处理订单附加数据
        orderProcessBService.processOrder(zsNormalUpdateOrderDTO, orderDTO);

        return orderDTO;
    }

    /**
     * 获取修改地址订单信息
     *
     * @param zsNormalAddressOrderDTO
     * @return
     * @throws OmsBaseException
     */
    protected OrderDTO getUpdateAddressOrderDTO(ZsNormalAddressOrderDTO zsNormalAddressOrderDTO) throws OmsBaseException {
        // 原始数据
        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(zsNormalAddressOrderDTO.getOrderId(), zsNormalAddressOrderDTO.getWorkId());
        OrderDetail dbOrderDetail = orderDetailService.findOrderDetailByKey(zsNormalAddressOrderDTO.getOrderId());

        zsNormalAddressOrderDTO.setTelephone2(StringUtils.defaultString(zsNormalAddressOrderDTO.getTelephone2()));
        zsNormalAddressOrderDTO.setTelephone3(StringUtils.defaultString(zsNormalAddressOrderDTO.getTelephone3()));

        Order order = BeanMapper.map(zsNormalAddressOrderDTO, Order.class);
        OrderDetail orderDetail = BeanMapper.map(zsNormalAddressOrderDTO, OrderDetail.class);
        OrderWork orderWork = BeanMapper.map(zsNormalAddressOrderDTO, OrderWork.class);

        // 保存订单
        OrderDTO orderDTO = BeanMapper.map(zsNormalAddressOrderDTO, OrderDTO.class);
        orderDTO.setOrder(order);
        orderDTO.setOrderDetail(orderDetail);
        orderDTO.setOrderWork(orderWork);

        // 原始数据
        orderDTO.setDbOrderWork(dbOrderWork);
        orderDTO.setDbOrderDetail(dbOrderDetail);

        // 修改时，用户ID不变
        orderWork.setPlat(dbOrderWork.getPlat());
        orderWork.setPlatWork(dbOrderWork.getPlatWork());
        orderWork.setSourceType(dbOrderWork.getSourceType());
        orderWork.setUserId(dbOrderWork.getUserId());
        orderWork.setChannelId(Optional.ofNullable(orderWork.getChannelId()).orElse(dbOrderWork.getChannelId()));
        orderWork.setChannelName(Optional.ofNullable(orderWork.getChannelName()).orElse(dbOrderWork.getChannelName()));
        orderWork.setChannelOneId(Optional.ofNullable(orderWork.getChannelOneId()).orElse(dbOrderWork.getChannelOneId()));
        orderWork.setChannelTwoId(Optional.ofNullable(orderWork.getChannelTwoId()).orElse(dbOrderWork.getChannelTwoId()));


        order.setPlat(dbOrderWork.getPlat());
        order.setPlatWork(dbOrderWork.getPlatWork());
        order.setUserId(dbOrderWork.getUserId());

        // 订单处理地址
        orderBService.processOrderAddress(orderDTO);
        // 城市id
        orderWork.setCityId(order.getCityId());
        // 行政城市id
        orderWork.setNaturalCityId(order.getNaturalCityId());

        return orderDTO;
    }

    /**
     * 更新原价
     *
     * @param orderWork
     * @throws OmsBaseException
     */
    protected void setOriginalAmount(OrderWork orderWork, Integer equtityId) throws OmsBaseException {

        // 原价处理
        if (!NumberUtil.isNullOrZero(orderWork.getOriginalAmount())) {
            log.debug("[{}]设置原价[{}]", orderWork.getWorkId(), orderWork);
            WorkUpdateAmountDTO updateAmountDTO = new WorkUpdateAmountDTO();
            updateAmountDTO.setOriginalAmount(orderWork.getOriginalAmount());
            updateAmountDTO.setOrderId(orderWork.getOrderId());
            updateAmountDTO.setWorkId(orderWork.getWorkId());
            orderWorkAmountBService.updateOriginalAmount(updateAmountDTO);
        }

    }

    /**
     *  返修单检测新逻辑
     *      1.判断是否为系统工单号
     *      2.如果为修改则判断是否原单号=当前工单号
     *      3.电话&经纬度&前台二级产品分类是否有其一相同
     *      4.原单是否有完成时间
     *      5.源单城市在当前角色城市数据权限内
     *      6.匹配服务商
     *      7.返修单只能在新单上创建
     *  @param checkReworkOrderDTO
     *  @return OrderReworkDTO
     *  @throws OmsBaseException
     *  @Modifier huangchao 2022/04/12 新增返修单校验逻辑 返修单只能在新单上创建
     */
    protected OrderReworkDTO checkReworkId(CheckReworkOrderDTO checkReworkOrderDTO) throws OmsBaseException{
        /*

         */
        logger.info("checkRewordId..............................");

        Long reworkId = checkReworkOrderDTO.getReworkId();
        Long orderId = checkReworkOrderDTO.getOrderId();

        if (null == reworkId) {
            throw new OmsBaseException("返修单号不能为空......");
        }

        // 判断是否与当前工单号相同
        if (Objects.nonNull(orderId) && Objects.equals(orderId,reworkId)) { //表示修改时，判断是否与原单号相同
            throw new OmsBaseException("不能和原单号重复");
        }

        // 原单号是否存在或正常
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(reworkId);
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(reworkId, reworkId);
        if (null == orderWork || null == orderDetail) {
            throw new OmsBaseException("无效返修单号-返修单不存在");
        }

        if (!Objects.equals(OrderConsts.ORDER_TYPE_NEW, orderWork.getType())) {
            throw new OmsBaseException("只能在新单上创建返修单");
        }

//        // 判断渠道
//        Integer channelId = checkReworkOrderDTO.getChannelId();
//        if (null!=channelId && !Objects.equals(orderWork.getChannelId(), channelId)) {
//            throw new OmsBaseException("无效返修单号-渠道不一致");
//        }

        // 判断服务平台
        Integer platWork = checkReworkOrderDTO.getPlatWork();
        if (null != platWork && !Objects.equals(orderWork.getPlatWork(), platWork)) {
            throw new OmsBaseException("无效返修单号-服务平台不一致");
        }

        // 判断原单是否有无完成时间
        if (Objects.isNull(orderWork.getCompleteTime())){
            throw new OmsBaseException("无效返修单号-工单在进行中");
        }

/*        // 原单-返修卡是否过期
        OrderWarranty orderWarranty = orderWarrantyService.findByOrderId(reworkId);
        if (orderWarranty != null && Objects.equals(OrderConsts.ORDER_WARRANTY_TYPE_CARD, orderWarranty.getType())) {
            List<OrderWarrantyProduct> orderWarrantyProductList = orderWarrantyProductService.listByOrderId(reworkId);
            if (CollectionUtils.isNotEmpty(orderWarrantyProductList)) {
                List<OrderWarrantyProduct> collect = orderWarrantyProductList.stream()
                        .filter(e -> e.getExpiredTime() != null)
                        .collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(collect)) {
                    boolean validTimeRange = collect.stream().anyMatch(e -> e.getExpiredTime().getTime() > DateUtil.getNow().getTime());
                    if (!validTimeRange) {
                        throw new OmsBaseException("无效返修单号-保修卡已过期");
                    }
                }
            }
        }*/

        // 原单-原单下有未完成进行中的返修单
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .filter(QueryBuilders.rangeQuery("status").lt(OrderStatusConsts.WORK_STATUS_COMPLETE))
                .filter(QueryBuilders.termQuery("resultStatus", OrderStatusConsts.WORK_RESULT_DOING))
                .filter(QueryBuilders.termQuery("reworkId", reworkId));
        NativeSearchQuery searchQuery = new NativeSearchQuery(queryBuilder);
        searchQuery.setPageable(PageRequest.of(0, 1, Sort.by(Sort.Order.asc("receiveTime"))));
        FetchSourceFilter fetchSourceFilter = new FetchSourceFilter(new String[]{"id"}, new String[]{});
        searchQuery.addSourceFilter(fetchSourceFilter);
        logger.debug("原单下有未完成进行中的返修单[{}]", searchQuery.getQuery().toString());
        List<EsOrderWork> page = orderWorkEsBService.listPageByQuery(searchQuery);
        if (CollectionUtil.isNotNullOrEmpty(page)) {
            Long doingWorkId = page.get(0).getId();
            if (NumberUtil.isNullOrZero(orderId) || !Objects.equals(orderId, doingWorkId)) {
                throw new OmsBaseException(OmsErrorCodeConsts.ORDER_INFO_REWORKING, "原单下有未完成进行中的返修单" + doingWorkId);
            }
        }


        // 电话&经纬度&前台二级产品分类是否有其一相同
        do {
            List<String> phoneList = Lists.newArrayListWithExpectedSize(6);
            phoneList.add(StringUtils.defaultIfBlank(orderDetail.getTelephone(), ""));
            phoneList.add(StringUtils.defaultIfBlank(orderDetail.getTelephone2(), ""));
            phoneList.add(StringUtils.defaultIfBlank(orderDetail.getTelephone3(), ""));
            phoneList.add(StringUtils.defaultIfBlank(checkReworkOrderDTO.getTelephone(), ""));
            phoneList.add(StringUtils.defaultIfBlank(checkReworkOrderDTO.getTelephone2(), ""));
            phoneList.add(StringUtils.defaultIfBlank(checkReworkOrderDTO.getTelephone3(), ""));
            long count = phoneList.stream().filter(e -> !"".equals(e)).count();
            long distinctCount = phoneList.stream().filter(e -> !"".equals(e)).distinct().count();
            // 三个用户电话是否有一个相同
            if (count > distinctCount) {//（数量>去重数量[存在相同号码]）
                break;
            }

            // 经纬度是否相等
            if (Objects.equals(checkReworkOrderDTO.getLatitude(), orderDetail.getLatitude()) && Objects.equals(checkReworkOrderDTO.getLongitude(), orderDetail.getLongitude())) {
                break;
            }

            Integer showProductId = basePlatService.getShowProductId(checkReworkOrderDTO.getProductId(), checkReworkOrderDTO.getProductShowType());

            // 比较前台产品是否相等
           if (Objects.nonNull(showProductId) && Objects.equals(showProductId, orderWork.getShowProductId())){
               break;
           }

           throw new OmsBaseException("无效返修单号-电话或产品不正确");
        }while(false);


        // 源单城市在当前角色城市数据权限内
//        if (Objects.nonNull(checkReworkOrderDTO.getCityId()) && !Objects.equals(orderWork.getCityId(), checkReworkOrderDTO.getCityId())) {
//            throw new OmsBaseException("返修单号不合法-城市不相同");
//        }

        // 匹配服务商
        Integer companyState = GlobalConsts.NONE;
        Integer companyId = orderWork.getManageCompanyId();
        ResponseDTO<CompanyDRO> companyResponse = null;

        // 获取原单服务商的状态
        logger.info("check rework order company state,service company:[{}]",companyId);
        do {
            if(NumberUtil.isNullOrZero(companyId)){
                break;
            }

            // 判断原单服务商是否在原单城市下还开通其他区县
            Integer cityId = orderWork.getCityId();
            ResponseDTO<List<VtDTO>> responseDTO = availableAreaListRemoteService.listAvailableAreaBySpIdLimitParentArea(companyId,
                    AvailableAreaLevelEnum.CITY, cityId, AvailableAreaLevelEnum.COUNTY);
            if (responseDTO.getData().isEmpty()) {
                logger.info("getAreaByCompanyIdAndCityId response is empty,company:[{}],city:[{}]", companyId, cityId);
                break;
            }

            companyState = GlobalConsts.NO;

            // 判断原单服务商的状态是否正常
            companyResponse = companyListRemoteService.getCompanyDROById(companyId);
            if (null == companyResponse || companyResponse.getData().getStatus() != GlobalConsts.STATUS_NORMOL) {
                logger.info("company status is not normal,company:[{}],cityId:[{}]",companyId,cityId);
                break;
            }

            companyState = GlobalConsts.YES;
        }while(false);

        OrderReworkDTO orderReworkDTO = new OrderReworkDTO();
        OrderWork curOrderWork = null;

        if (Objects.nonNull(orderId)) {
            curOrderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        }

        if (null == orderId || null == curOrderWork) {

            //如果为新增订单，并且服务商的状态正常，则返回对应的服务商
            if (companyState == GlobalConsts.YES) {
                getOrderReworkDTO(orderReworkDTO, orderWork, orderDetail);
            }

            return orderReworkDTO;
        }

        // 修改订单
        Integer curCompanyId = curOrderWork.getManageCompanyId();

        do {
            //判断当前工单有服务商
            if(NumberUtil.isNullOrZero(curCompanyId)){
                break;
            }
            ResponseDTO<CompanyDRO> curCompanyResponse = companyListRemoteService.getCompanyDROById(companyId);
            if (Objects.isNull(curCompanyResponse)) {
                break;
            }


            // 判断当前工单服务商与原单服务商是否一致
            /*if (!Objects.equals(companyId,curCompanyId)) {
                throw new OmsBaseException("无效返修单号-服务商不一致");
            }*/

            // 判断源单城市，当前服务商仍然开通？
            if (companyState == GlobalConsts.NONE &&
                    !Objects.equals(com.zmn.oms.common.constant.CompanyConsts.YEYX_SPECIAL_MANAGE_COMPANY_ID, curCompanyId)) {
                throw new OmsBaseException("无效返修单号-服务商已停止");
            }

        } while (false);

        // 返回对应的服务商
        if (companyState == GlobalConsts.YES) {
            getOrderReworkDTO(orderReworkDTO,orderWork,orderDetail);
        }

        return orderReworkDTO;
    }

    /**
     * 冻结金额
     *
     * @param orderDTO
     */
    protected void saveFactoryFreezeAmount(OrderDTO orderDTO) throws OmsBaseException {
        factoryAccountModifyBService.freeze(orderDTO);
    }

    /**
     * 返修单检测返回数据
     *
     * @param orderReworkDTO
     * @param orderWork
     * @param orderDetail
     */

    protected void getOrderReworkDTO(OrderReworkDTO orderReworkDTO,OrderWork orderWork,OrderDetail orderDetail){
        if (Objects.isNull(orderReworkDTO)) {
            return;
        }

        if (Objects.nonNull(orderWork)) {
            orderReworkDTO.setOrderId(orderWork.getOrderId());
            orderReworkDTO.setCompanyId(orderWork.getCompanyId());
            orderReworkDTO.setCompanyName(orderWork.getCompanyName());
            orderReworkDTO.setManageCompanyId(orderWork.getManageCompanyId());
            orderReworkDTO.setManageCompanyName(orderWork.getManageCompanyName());
            orderReworkDTO.setManageCompanyType(orderWork.getManageCompanyType());
            orderReworkDTO.setPlat(orderWork.getPlat());
            orderReworkDTO.setPlatWork(orderWork.getPlatWork());
            orderReworkDTO.setType(orderWork.getType());
            orderReworkDTO.setCityId(orderWork.getCityId());
            orderReworkDTO.setNaturalCityId(orderWork.getNaturalCityId());
        }

        if (Objects.nonNull(orderDetail)) {
            orderReworkDTO.setProvinceId(orderDetail.getProvinceId());
            orderReworkDTO.setProvinceName(orderDetail.getProvinceName());
            orderReworkDTO.setCityName(orderDetail.getCityName());
            orderReworkDTO.setNaturalCityName(orderDetail.getNaturalCityName());
            orderReworkDTO.setCountyId(orderDetail.getCountyId());
            orderReworkDTO.setCountyName(orderDetail.getCountyName());
            orderReworkDTO.setStreetId(orderDetail.getStreetId());
            orderReworkDTO.setStreet(orderDetail.getStreet());
            orderReworkDTO.setAddress(orderDetail.getAddress());
            orderReworkDTO.setLatitude(orderDetail.getLatitude());
            orderReworkDTO.setLongitude(orderDetail.getLongitude());
        }
    }

}
